package com.sdkj.dspservice.modules.demand.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdkj.dspservice.common.base.controller.BaseController;
import com.sdkj.dspservice.common.base.entity.BaseResult;
import com.sdkj.dspservice.common.config.Global;
import com.sdkj.dspservice.common.constant.Consts;
import com.sdkj.dspservice.common.constant.HttpStatus;
import com.sdkj.dspservice.common.react.AntdProResult;
import com.sdkj.dspservice.common.utils.MybatisPlusUtils;
import com.sdkj.dspservice.common.utils.StringUtils;
import com.sdkj.dspservice.common.utils.UserUtils;
import com.sdkj.dspservice.modules.demand.entity.Demand;
import com.sdkj.dspservice.modules.demand.entity.DemandDetails;
import com.sdkj.dspservice.modules.demand.entity.DemandType;
import com.sdkj.dspservice.modules.demand.service.DemandDetailsService;
import com.sdkj.dspservice.modules.demand.service.DemandService;
import com.sdkj.dspservice.modules.demand.service.DemandTypeService;
import com.sdkj.dspservice.modules.sys.entity.Annex;
import com.sdkj.dspservice.modules.sys.entity.Role;
import com.sdkj.dspservice.modules.sys.entity.User;
import com.sdkj.dspservice.modules.sys.service.AnnexService;
import com.sdkj.dspservice.modules.sys.service.UserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 需求类型表Controller
 *
 * @author tm
 */
@RestController
@RequestMapping(value = "${project-config.apiUrl}/${project-config.version}/demand/demand")
public class DemandController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private DemandService demandService;
    @Autowired
    private DemandTypeService demandTypeService;
    @Autowired
    private DemandDetailsService demandDetailsService;
    @Autowired
    private AnnexService annexService;

    //    @RequiresPermissions("demand:demand:view")
    @RequestMapping(value = "get")
    public AntdProResult get(String id) {
        AntdProResult result = new AntdProResult();
        if (StringUtils.isNotBlank(id)) {
            Demand demand = demandService.getById(id);
            // 插入当前登录用户
            demand.setCurrentUser(UserUtils.getCurrentUser());
            // 关联出创建用户
            User createByUser = userService.getById(demand.getCreateBy());
            demand.setCreateByUser(createByUser);
            // 关联出当前流程用户
            User nowUser = userService.getById(demand.getCreateBy());
            demand.setNowUser(nowUser);
            // 关联出类型
            DemandType type = demandTypeService.getById(demand.getTypeId());
            demand.setType(type);
            result.setData(demand);
        } else {
            result.error(HttpStatus.STATUS_400,
                    "id不能为空");
        }
        return result;
    }

    //    @RequiresPermissions("demand:demand:view")
    @RequestMapping(value = "list")
    public AntdProResult list(Demand demand) {
        AntdProResult result = new AntdProResult();
        // 获取当前用户
        User currentUser = UserUtils.getCurrentUser();
        // 获取当前用户ID
        String currentUserId = currentUser.getId();
        // 制作sql条件
        QueryWrapper<Demand> queryWrapper = new QueryWrapper();
        // 判断findType的值，前提为发起或参与该需求，0、全部需求  1、待办需求（当前流程用户为我）  2、流转中需求（除了待办、已完成）   3、已完成需求
        // 先筛选出发起或参与的需求，即需求详情中，任意一条有当前用户，或createBy为当前用户的
        List<String> demandIdList = demandDetailsService.list().stream().filter(demandDetails -> currentUserId.equals(demandDetails.getUserId())).map(DemandDetails::getDemandId).distinct().collect(Collectors.toList());
        queryWrapper.and(i -> i.in("a.id", demandIdList.isEmpty() ? MybatisPlusUtils.newListContainNull() : demandIdList).or().eq("a.create_by", currentUserId));
        switch (demand.getFindType()) {
            case "1":
                // 待办需求（当前流程用户为我），nowUser为当前登录用户，且不为已关闭或已完成
                queryWrapper.eq("a.now_user_id", currentUserId);
                queryWrapper.notIn("a.flow_status", Demand.FLOW_STATUS_ClOSE, Demand.FLOW_STATUS_FINISH);
                break;
            case "2":
                // 流转中需求（除了待办、已完成），nowUser不为当前登录用户，且不为已关闭或已完成
                queryWrapper.ne("a.now_user_id", currentUserId);
                queryWrapper.notIn("a.flow_status", Demand.FLOW_STATUS_ClOSE, Demand.FLOW_STATUS_FINISH);
                break;
            case "3":
                // 已完成需求
                queryWrapper.eq("a.flow_status", Demand.FLOW_STATUS_FINISH);
                break;
        }
        // 处理实体里的查询参数
        demand.makeQueryWrapper(queryWrapper);
        // 查询
        IPage<Demand> demandPage = demandService.pageLink(new Page<>(demand.current, demand.pageSize), queryWrapper);
        List<Demand> demandList = demandPage.getRecords();
        // 给所有数据插入当前用户（前端有时获取不到，干脆在这里加）
        for (Demand d : demandList) {
            d.setCurrentUser(currentUser);
        }
        // 不显示已关闭的需求
        demandList = demandList.stream().filter(nd -> !Demand.FLOW_STATUS_ClOSE.equals(nd.getStatus())).collect(Collectors.toList());
        demandPage.setRecords(demandList);
        result.success(demandPage);
        return result;
    }

    //    @RequiresPermissions("demand:demand:edit")
    @RequestMapping(value = "save", produces = MediaType.APPLICATION_JSON_VALUE)
    public BaseResult save(@Valid @RequestBody Demand demand) {
        BaseResult result = new BaseResult();
        boolean isNewRecord = demand.isNewRecord();
        Demand demandSave;
        // 新纪录或者草稿状态或者status为空状态（有id的新纪录）
        if (isNewRecord || Demand.STATUS_DRAFT.equals(demand.getStatus())) {
            demandSave = demand;
        } else {
            // 只能修改需求说明和附件
            demandSave = demandService.getById(demand.getId());
            demandSave.setDescription(demand.getDescription());
            demandSave.setAnnexIds(demand.getAnnexIds());
            demandSave.setIsIssue(demand.getIsIssue());
        }
        demandService.saveOrUpdate(demandSave);
        // 草稿状态，并且需要直接发布
        if (Demand.STATUS_DRAFT.equals(demandSave.getStatus()) && Global.YES.equals(demandSave.getIsIssue())) {
            demandService.startAndIssue(demandSave.getId());
        }
        result.setData(demandSave);
        return result;
    }

    //    @RequiresPermissions("demand:demand:edit")
    @RequestMapping(value = "remove")
    public BaseResult delete(String id, HttpServletResponse response) {
        BaseResult result = new BaseResult();
        if (StringUtils.isNotBlank(id)) {
            demandService.removeById(id);
        } else {
            response.setStatus(HttpStatus.STATUS_400);
            result.setErrorMessage("id不能为空");
        }
        return result;
    }

    /**
     * 获取数据源select列表
     *
     * @param demand
     * @return
     */
    @ApiOperation(value = "获取select列表")
    @GetMapping(value = "listForSelect")
    public AntdProResult listForSelect(Demand demand) {
        AntdProResult result = new AntdProResult();
        List<Demand> demandList = demandService.list(demand);
        // 转换为{label:xxx,value:xxx}
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Demand r : demandList) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("label", r.getName());
            map.put("value", r.getId());
            mapList.add(map);
        }
        result.success(mapList);
        return result;
    }

    /**
     * 需求流程流转
     *
     * @param demandDetails
     * @return
     */
    @ApiOperation(value = "需求流程流转")
    @RequestMapping(value = "flow")
    public AntdProResult flow(@Valid @RequestBody DemandDetails demandDetails) {
        AntdProResult result = new AntdProResult();
        demandService.flow(demandDetails);
        return result;
    }

    /**
     * 开始并直接到待审核
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "开始并直接到待审核")
    @RequestMapping(value = "startAndIssue")
    public AntdProResult startAndIssue(String id) {
        AntdProResult result = new AntdProResult();
        demandService.startAndIssue(id);
        return result;
    }

    /**
     * 获取流程流转可选用户select形式
     *
     * @param id 需求ID
     * @return
     */
    @ApiOperation(value = "获取流程流转可选用户")
    @RequestMapping(value = "findCanFlowUserList")
    public AntdProResult findCanFlowUserList(String id) {
        AntdProResult result = new AntdProResult();
        // 查询需求
        Demand demand = demandService.getById(id);
        // 获取需求当前流程状态
        String flowStatus = demand.getFlowStatus();
        // 根据当前流程状态，获取不同的可选用户
        List<User> userList;
        switch (flowStatus.trim()) {
            // 已提交，可选用户为角色是项目负责人
            case Demand.FLOW_STATUS_SUBMITTED:
                userList = userService.listByRoleEnName(Role.EN_NAME_DIRECTOR);
                break;
            // 待审核，可选用户为角色是需求分派人
            case Demand.FLOW_STATUS_VERIFY:
                userList = userService.listByRoleEnName(Role.EN_NAME_ASSIGN);
                break;
            // 待分派，可选用户为角色是需求处理人
            case Demand.FLOW_STATUS_DISTRIBUTION:
                userList = userService.listByRoleEnName(Role.EN_NAME_HANDLE);
                break;
            default:
                userList = new ArrayList<>();
        }
        result.success(userList);
        return result;
    }

    /**
     * 获取详情列表
     *
     * @param demandDetails
     * @return
     */
//    @RequiresPermissions("demand:demand:view")
    @RequestMapping(value = "detailsList")
    public AntdProResult detailsList(@Valid @RequestBody DemandDetails demandDetails) {
        AntdProResult result = new AntdProResult();
        QueryWrapper<DemandDetails> queryWrapper = new QueryWrapper<>();
        demandDetails.makeQueryWrapper(queryWrapper);
        queryWrapper.orderByAsc("a.flow_sort");
        List<DemandDetails> demandDetailsList = demandDetailsService.listLink(queryWrapper);
        // 所有的详情描述和决策意见，都往前一个流程插入
        List<String> descriptionList = demandDetailsList.stream().map(DemandDetails::getDescription).collect(Collectors.toList());
        List<String> makeTypeList = demandDetailsList.stream().map(DemandDetails::getMakeType).collect(Collectors.toList());
        int i = 1;
        for (DemandDetails d : demandDetailsList) {
            if (i != descriptionList.size()) {
                d.setDescription(descriptionList.get(i));
                d.setMakeType(makeTypeList.get(i));
            } else {
                d.setDescription(null);
                d.setMakeType(null);
            }
            ++i;
        }
        result.success(demandDetailsList);
        return result;
    }

    @RequestMapping(value = "annexList")
    public AntdProResult annexList(String id) {
        AntdProResult result = new AntdProResult();
        // 获取annexIds
        Demand demand = demandService.getById(id);
        if (demand != null) {
            List<Annex> list = new ArrayList<>();
            if (StringUtils.isNotBlank(demand.getAnnexIds())) {
                list = annexService.listByIds(demand.getAnnexIds());
            }
            result.success(list);
        } else {
            result.error(AntdProResult.VALIDATOR_ERROR, "id");
        }
        return result;
    }

    @RequestMapping(value = "saveAnnex")
    public AntdProResult saveAnnex(String id, String annexId) {
        AntdProResult result = new AntdProResult();
        // 获取annexIds
        Demand demand = demandService.getById(id);
        demand.setAnnexIds(StringUtils.addFromStrings(annexId, demand.getAnnexIds()));
        demandService.saveOrUpdate(demand);
        return result;
    }

    @RequestMapping(value = "deleteAnnexByIds")
    public AntdProResult deleteAnnexByIds(String id, String annexIds) {
        AntdProResult result = new AntdProResult();
        // 获取annexIds
        Demand demand = demandService.getById(id);
        demand.setAnnexIds(StringUtils.deleteFromStrings(annexIds, demand.getAnnexIds(), Consts.COMMA));
        demandService.saveOrUpdate(demand);
        return result;
    }

}